package net.pimpas.web.jsf.renderers.group.html;

import java.io.IOException;

import javax.faces.component.UIComponent;
import javax.faces.component.html.HtmlOutputText;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.render.Renderer;

import net.pimpas.web.jsf.components.fieldset.UIFieldset;
import net.pimpas.web.jsf.components.graphicimage.UIGraphicImage;
import net.pimpas.web.jsf.components.group.UIGroup;
import net.pimpas.web.jsf.components.legend.UILegend;
import net.pimpas.web.jsf.components.span.UISpan;
import net.pimpas.web.jsf.renderers.RendererBase;
import net.pimpas.web.jsf.util.ComponentUtils;

import org.apache.myfaces.shared_impl.renderkit.RendererUtils;
import org.apache.myfaces.shared_impl.renderkit.html.HTML;

public class HtmlGroupRenderer extends RendererBase {

	@Override
	public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
		if(!component.isRendered()) return;
		if(!ComponentUtils.isCorrectComponentType(component, UIGroup.class)) return;
		
		super.initResourceManager(context, component);
		
		UIGroup group = (UIGroup) component;
		
		ResponseWriter writer = context.getResponseWriter();
		writer.startElement(HTML.SPAN_ELEM, component);
		writer.writeAttribute(HTML.ID_ATTR, component.getClientId(context), null);
		
		// imports
		this.processImports( context, group );
	}
	
	@SuppressWarnings("unchecked")
	private void processFieldSet(FacesContext context, UIGroup group) throws IOException {
		UIComponent cp = ComponentUtils.getComponentById(group, context, group.getId()+UIGroup.FIELDSET_ID, ComponentUtils.SERVER_ID);
		if(cp != null) return;
		
		UIFieldset fs = (UIFieldset) context.getApplication().createComponent(UIFieldset.COMPONENT_TYPE);
		fs.setNoId(Boolean.TRUE);
		fs.setStyleClass(UIGroup.DEFAULT_STYLE_CLASS);
		fs.setId(group.getId()+UIGroup.FIELDSET_ID);
		
		UILegend legend = (UILegend) context.getApplication().createComponent(UILegend.COMPONENT_TYPE);
		legend.setNoId(Boolean.TRUE);
		legend.setStyleClass(UIGroup.DEFAULT_LEGEND_STYLE_CLASS);
		
		UISpan icon = (UISpan) context.getApplication().createComponent(UISpan.COMPONENT_TYPE);
		icon.setNoId(Boolean.TRUE);
		//icon.setStyleClass(UIGroup.DEFAULT_LABEL_STYLE_CLASS);
		
		UIGraphicImage img = (UIGraphicImage) context.getApplication().createComponent(UIGraphicImage.COMPONENT_TYPE);
		img.setUrl(this.getUrlIcon(context, group));
		img.setStyleClass(UIGroup.DEFAULT_LABEL_STYLE_CLASS);
		
		UISpan text = (UISpan) context.getApplication().createComponent(UISpan.COMPONENT_TYPE);
		text.setNoId(Boolean.TRUE);
		text.setStyleClass(UIGroup.DEFAULT_TEXT_STYLE_CLASS);
		text.setTabIndex("-1");
		
		HtmlOutputText output = (HtmlOutputText) context.getApplication().createComponent(HtmlOutputText.COMPONENT_TYPE);
		output.setValue(group.getTitle());
		
		text.getChildren().add(output);
		icon.getChildren().add(img);
		legend.getChildren().add(icon);
		legend.getChildren().add(text);
		
		fs.getChildren().add(legend);
		
		UISpan content = (UISpan) context.getApplication().createComponent(UISpan.COMPONENT_TYPE);
		content.setNoId(Boolean.FALSE);
		content.setStyleClass(UIGroup.DEFAULT_CONTENT_STYLE_CLASS);
		content.setId(group.getId()+UIGroup.CONTENT_ID);
		
		fs.getChildren().add(content);
		group.getChildren().add(fs);
	}
	
	@Override
	public void encodeChildren(FacesContext context, UIComponent component) throws IOException {
		if(!component.isRendered()) return;
		if(!ComponentUtils.isCorrectComponentType(component, UIGroup.class)) return;
		
		super.initResourceManager(context, component);
		
		// write fieldSet
		this.processFieldSet(context, (UIGroup) component);
		
		UIComponent fieldset = ComponentUtils.getComponentById(component, context, component.getId()+UIGroup.FIELDSET_ID, ComponentUtils.SERVER_ID);
		UIComponent content = ComponentUtils.getComponentById(component, context, component.getId()+UIGroup.CONTENT_ID, ComponentUtils.SERVER_ID);
		
		Renderer fieldsetRender = context.getRenderKit().getRenderer(UIFieldset.COMPONENT_FAMILY, UIFieldset.COMPONENT_RENDER_TYPE);
		fieldsetRender.encodeBegin(context, fieldset);
		for(int i=0;i<fieldset.getChildren().size();i++)
			if(fieldset.getChildren().get(i) != content)
				RendererUtils.renderChild(context, (UIComponent) fieldset.getChildren().get(i));
		
		Renderer spanRender = context.getRenderKit().getRenderer(UISpan.COMPONENT_FAMILY, UISpan.COMPONENT_RENDER_TYPE);
		
		spanRender.encodeBegin(context, content);
		
		// TODO shared?!
		renderContent(context, component);
		
		spanRender.encodeEnd(context, content);
	}
		
	
	public static void renderContent(FacesContext context, UIComponent component) throws IOException {
		if(!component.isRendered()) return;
		if(!ComponentUtils.isCorrectComponentType(component, UIGroup.class)) return;
		
		UIComponent fieldset = ComponentUtils.getComponentById(component, context, component.getId()+UIGroup.FIELDSET_ID, ComponentUtils.SERVER_ID);
		
		for(int i=0;i<component.getChildren().size();i++)
			if(component.getChildren().get(i) != fieldset)
				RendererUtils.renderChild(context, (UIComponent) component.getChildren().get(i));
	}
	
	private String getUrlIcon(FacesContext context, UIGroup group) {
		if(group.getIcon().equals(UIGroup.DEFAULT_ICON))
			return this.getResourceManager().getResourceUri("images/"+group.getIcon());
			
		return group.getIcon();
	}

	private void processImports(FacesContext context, UIGroup component) {
		if(!component.getStyleClass().equals(UIGroup.DEFAULT_STYLE_CLASS))
			this.getResourceManager().addStylesheetHere(component.getStyleClass());
		else
			this.getResourceManager().addStylesheetHeader("css/"+UIGroup.DEFAULT_STYLE_FILE);
	}

	@Override
	public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
		if(!component.isRendered()) return;
		if(!ComponentUtils.isCorrectComponentType(component, UIGroup.class)) return;
		
		
		UIComponent fieldset = ComponentUtils.getComponentById(component, context, component.getId()+UIGroup.FIELDSET_ID, ComponentUtils.SERVER_ID);
		Renderer fieldsetRender = context.getRenderKit().getRenderer(UIFieldset.COMPONENT_FAMILY, UIFieldset.COMPONENT_RENDER_TYPE);
		fieldsetRender.encodeEnd(context, fieldset);
		ResponseWriter writer = context.getResponseWriter();
		
		writer.endElement(HTML.SPAN_ELEM);
	}
}